import 'package:safetymonitor/app/core/core.dart';
import 'package:safetymonitor/app/core/ext/widget_extension.dart';
import 'package:safetymonitor/app/data/common/choice_bean.dart';

class CustomTreePicker extends StatefulWidget {
  const CustomTreePicker({
    required this.treeData,
    super.key,
    this.initial,
    this.accentColor,
    this.itemBuilder,
    this.tabBuilder,
  });

  final List<TreeChoiceIface> treeData;
  final TreeChoiceIface? initial;
  final Color? accentColor;
  final Widget Function(TreeChoiceIface item, bool selected)? itemBuilder;
  final Widget Function(Key key, TreeChoiceIface? item, bool selected)? tabBuilder;

  @override
  State<CustomTreePicker> createState() => _CustomTreePickerState();
}

class _CustomTreePickerState extends State<CustomTreePicker> with SingleTickerProviderStateMixin {
  static const _tabTitleStyle = TextStyle(fontSize: 14, color: Colors.black);
  static const _itemTitleStyle = TextStyle(fontSize: 14, color: Colors.black);

  late final animeCtrl = AnimationController(duration: Durations.short4, vsync: this);
  late final _curvedAnimation = CurvedAnimation(parent: animeCtrl, curve: Curves.easeInOutCubic);
  late Animation<double> _sliderAnimation = Tween<double>(
    begin: 0,
    end: 10,
  ).animate(_curvedAnimation);
  final _sliderFixMargin = ValueNotifier(0.0);
  static const double _sliderWidth = 20;

  final _pageController = PageController(initialPage: 0);

  final _sliderKey = GlobalKey();
  final List<GlobalKey> _tabKeys = [];

  late final _maxDepth = widget.treeData.fold<int>(0, (p, e) => p > e.depth ? p : e.depth) + 1;

  /// 选择器数据集合
  late final List<List<TreeChoiceIface>> _pagesData = [widget.treeData];

  /// 已选择的title集合
  final List<TreeChoiceIface?> _selectedTabs = [null];

  /// 已选择的item index集合
  final List<int> _selectedIndexes = [-1];

  /// "请选择"tab宽度，添加新的tab时用到
  double _animTabWidth = 0;

  /// tab添加事件记录，用于隐藏"请选择"tab初始化状态
  bool _isAddTabEvent = false;

  /// tab移动未开始，渲染'请选择'tab时隐藏文本，这时的tab在终点位置
  bool _isAnimateTextHide = false;

  /// 防止_moveSlider重复调用
  bool _isClickAndMoveTab = false;

  /// 当前选择的页面，移动滑块前赋值
  int _currentSelectPage = 0;

  MediaQueryData? _media;

  @override
  void didChangeDependencies() {
    _media = MediaQuery.of(context);
    super.didChangeDependencies();
  }

  @override
  void initState() {
    super.initState();

    //_initSelected();

    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      final tabBox = _tabKeys.first.currentContext?.findRenderObject() as RenderBox;
      _sliderFixMargin.value = (tabBox.size.width - _sliderWidth) / 2;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _buildBtns(),
        AnimatedBuilder(
          animation: _sliderAnimation,
          builder: (context, child) => Stack(
            clipBehavior: Clip.hardEdge,
            alignment: Alignment.bottomLeft,
            children: [
              SizedBox(
                width: _media?.size.width,
                height: 37.w,
                child: ListView(
                  scrollDirection: Axis.horizontal,
                  children: _buildTab(),
                ),
              ),
              ValueListenableBuilder<double>(
                valueListenable: _sliderFixMargin,
                builder: (_, margin, __) => Positioned(
                  left: margin + _sliderAnimation.value,
                  child: Container(
                    key: _sliderKey,
                    width: _sliderWidth,
                    height: 2,
                    decoration: BoxDecoration(
                      color: widget.accentColor,
                      borderRadius: BorderRadius.circular(2),
                    ),
                  ),
                ),
              )
            ],
          ),
        ),
        AppGaps.vGap10,
        Expanded(
          child: PageView.builder(
            itemCount: _pagesData.length,
            controller: _pageController,
            itemBuilder: (context, index) => _buildList(index),
            onPageChanged: (position) {
              if (!_isClickAndMoveTab) {
                _moveSlider(position, movePage: false);
              }
              if (_currentSelectPage == position) {
                _isClickAndMoveTab = false;
              }
            },
          ),
        )
      ],
    );
  }

  Widget _buildBtns() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        TextButton(
          onPressed: Get.back,
          child: Text(
            '取消',
            style: TextStyle(color: widget.accentColor),
          ),
        ),
        TextButton(
          onPressed: () {
            for (int idx = _selectedTabs.length - 1; idx >= 0; idx--) {
              final item = _selectedTabs[idx];
              if (item != null) {
                Navigator.of(context).pop(item);
                return;
              }
            }
            Navigator.of(context).pop(null);
          },
          child: Text(
            '确定',
            style: TextStyle(color: widget.accentColor),
          ),
        ),
      ],
    );
  }

  void _loadNextPageData(
    int page,
    int atIndex,
    TreeChoiceIface currentPageItem, {
    /// 是否是更新下一页
    bool isUpdatePage = false,
  }) {
    final List<TreeChoiceIface> data = [];
    if (page == 0) {
      data.addAll(widget.treeData);
    } else {
      data.addAll(currentPageItem.treeChildren ?? []);
    }

    final nextPageDataIsEmpty = data.isEmpty;
    if (!nextPageDataIsEmpty) {
      setState(() {
        if (isUpdatePage) {
          _pagesData[page] = data;
          _selectedTabs[page] = null;
          _selectedIndexes[page] = -1;

          _pagesData.removeRange(page + 1, _pagesData.length);
          _selectedIndexes.removeRange(page + 1, _selectedIndexes.length);
          _selectedTabs.removeRange(page + 1, _selectedTabs.length);
        } else {
          /// 添加新页面
          _isAnimateTextHide = true;
          _isAddTabEvent = true;
          _pagesData.add(data);
          _selectedTabs.add(null);
          _selectedIndexes.add(-1);
        }
        WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
          _moveSlider(page, isAdd: true);
        });
      });
    } else {
      final currentPage = page - 1;
      setState(() {
        _selectedTabs[currentPage] = currentPageItem;
        _selectedIndexes[currentPage] = atIndex;

        _pagesData.removeRange(page, _pagesData.length);
        _selectedIndexes.removeRange(page, _selectedIndexes.length);
        _selectedTabs.removeRange(page, _selectedTabs.length);
        WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
          _moveSlider(currentPage);
        });
      });
    }
  }

  void _moveSlider(int page, {bool movePage = true, bool isAdd = false}) {
    if (movePage && _currentSelectPage != page) {
      /// 上一次选择的页面和本次选择的页面不同时，移动tab标签，
      /// 移动时先把_isClickAndMoveTab设为true，防止滑动PageView
      /// 时_moveSlider重复调用。
      _isClickAndMoveTab = true;
    }
    _isAddTabEvent = isAdd;
    _currentSelectPage = page;

    if (animeCtrl.isAnimating) {
      animeCtrl.stop();
    }
    final slider = _sliderKey.currentContext?.findRenderObject() as RenderBox;
    final sliderPosition = slider.localToGlobal(Offset.zero);
    final currentTabBox = _tabKeys[page].currentContext?.findRenderObject() as RenderBox;
    final currentTabPosition = currentTabBox.localToGlobal(Offset.zero);

    _animTabWidth = currentTabBox.size.width;

    final begin = sliderPosition.dx - _sliderFixMargin.value;
    final end = currentTabPosition.dx + (currentTabBox.size.width - _sliderWidth) / 2 - _sliderFixMargin.value;
    _sliderAnimation = Tween<double>(begin: begin, end: end).animate(_curvedAnimation);
    animeCtrl.value = 0;
    animeCtrl.forward();
    if (movePage) {
      _pageController.animateToPage(
        page,
        curve: Curves.easeInOutCubic,
        duration: Durations.medium1,
      );
    }
  }

  /// tab标签添加动画
  Widget _buildTabAnime(Widget tab) {
    return Transform.translate(
      offset: Offset(Tween<double>(begin: _isAddTabEvent ? -_animTabWidth : 0, end: 0).evaluate(_curvedAnimation), 0),
      child: Opacity(
        opacity: _isAnimateTextHide ? 0 : 1,
        child: tab,
      ),
    );
  }

  /// 顶部tab
  List<Widget> _buildTab() {
    final widgets = <Widget>[];
    _tabKeys.clear();
    for (int i = 0; i < _pagesData.length; i++) {
      final key = GlobalKey();
      _tabKeys.add(key);
      final treeItem = _selectedTabs[i];
      final isSelected = _currentSelectPage == i;
      final tab = InkWell(
        child: widget.tabBuilder?.call(key, treeItem, isSelected) ??
            Container(
              key: key,
              height: 43,
              alignment: Alignment.center,
              padding: EdgeInsets.symmetric(horizontal: 13.w),
              child: ConstrainedBox(
                constraints: BoxConstraints(
                  maxWidth: (_media?.size.width ?? 0) / 3,
                ),
                child: Text(
                  treeItem?.treeName ?? '请选择',
                  style: isSelected ? _tabTitleStyle.copyWith(color: widget.accentColor) : _tabTitleStyle,
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                ),
              ),
            ),
        onTap: () {
          _moveSlider(i);
        },
      );
      if (i == _pagesData.length - 1 && _selectedTabs[i] == null) {
        widgets.add(_buildTabAnime(tab));
        _isAnimateTextHide = false;
      } else {
        widgets.add(tab);
      }
    }
    return widgets.joinWith(
      Icon(
        Icons.keyboard_arrow_right,
        size: 17.w,
      ),
    );
  }

  /// 单个选择项
  Widget _buildListItem(int index, int page, TreeChoiceIface item) {
    final isSelected = item == _selectedTabs[page];
    return InkWell(
      child: widget.itemBuilder?.call(item, isSelected) ??
          Container(
            alignment: Alignment.centerLeft,
            padding: EdgeInsets.symmetric(horizontal: 15.w),
            margin: EdgeInsets.symmetric(horizontal: 13.w),
            height: 43,
            decoration: BoxDecoration(
              color: isSelected ? widget.accentColor : null,
              borderRadius: isSelected ? BorderRadius.circular(13.w) : null,
            ),
            child: Text(
              item.treeName,
              style: isSelected ? _itemTitleStyle.copyWith(color: Colors.white) : _itemTitleStyle,
            ),
          ),
      onTap: () {
        if (page == _maxDepth - 1) {
          setState(() {
            _selectedTabs[page] = item;
            _selectedIndexes[page] = index;

            WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
              _moveSlider(page);
            });
          });
        } else if (_tabKeys.length >= _maxDepth || page < _tabKeys.length - 1) {
          if (index == _selectedIndexes[page]) {
            _moveSlider(page + 1);
          } else {
            setState(() {
              _selectedTabs[page] = item;
              _selectedIndexes[page] = index;
            });
            _loadNextPageData(page + 1, index, item, isUpdatePage: true);
          }
        } else {
          /// 添加新tab页面
          _selectedTabs[page] = item;
          _selectedIndexes[page] = index;
          _loadNextPageData(page + 1, index, item);
        }
      },
    );
  }

  /// 选择列表
  Widget _buildList(int page) {
    return ListView.builder(
      padding: EdgeInsets.zero,
      itemCount: _pagesData[page].length,
      itemBuilder: (context, index) => _buildListItem(
        index,
        page,
        _pagesData[page][index],
      ),
    );
  }

  void _initSelected() {
    final initial = widget.initial;
    if (initial != null) {
      final path = _findPathById(
        SimpleTree(
          treeId: '0',
          treeName: 'root',
          treeChildren: widget.treeData,
        ),
        initial,
      );
      path?.skip(1);
      _selectedTabs.clear();
      _selectedTabs.addAll(path ?? []);
    }
  }

  List<TreeChoiceIface>? _findPathById(TreeChoiceIface root, TreeChoiceIface target) {
    // 检查当前节点是否为目标节点
    if (root.treeId == target.treeId) {
      return [root];
    }

    // 如果当前节点有子节点，遍历子节点
    if (root.treeChildren != null) {
      for (var child in root.treeChildren!) {
        final path = _findPathById(child, target);
        // 如果在子树中找到了目标节点，将当前节点添加到路径中并返回
        if (path != null) {
          path.insert(0, root); // 将当前节点添加到路径的开头
          return path;
        }
      }
    }

    // 如果当前节点不是目标节点，也不是目标节点的祖先，则返回null
    return null;
  }
}
